#include <stdlib.h>
#include <stdio.h>
#include <nds.h>
#include <xlibrary.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <dirent.h>
#include <alloca.h>

// common headers
#include "common.h"

// local headers
#include "plugin.h"
#include "library.h"
#include "video.h"	// for consoleSet
#include "keysinstance.h"
#include "sound.h"
#include "filelist.h"   // for fl_*()

#include "slibs.h"

extern sStd _std;
extern const char *__ctype_ptr__;
void slibsInit() {
	_std.__ctype_ptr__=(char *)__ctype_ptr__;
}

int iprintf_dbg(const char *format, ...) {
	int ret;

	consoleSet(cMAIN);

	va_list args;
	va_start(args, format);
	ret=viprintf(format, args);
	va_end(args);

	consoleSet(cSUB);

	return ret;
}

int printf_dbg(const char *format, ...) {
	int ret;

	consoleSet(cMAIN);

	va_list args;
	va_start(args, format);
	ret=vprintf(format, args);
	va_end(args);

	consoleSet(cSUB);

	return ret;
}

int viprintf_dbg(const char *format, va_list ap) {
	int ret;

	consoleSet(cMAIN);

	ret=viprintf(format, ap);

	consoleSet(cSUB);

	return ret;
}

int vprintf_dbg(const char *format, va_list ap) {
	int ret;

	consoleSet(cMAIN);

	ret=vprintf(format, ap);

	consoleSet(cSUB);

	return ret;
}

void *alloca_no_macro(size_t sz) {	// alloca() is a macro
	return alloca(sz);
}

void __aeabi_idiv();
void __aeabi_idivmod();
void __aeabi_uidiv();
void __aeabi_ldivmod();

sStd _std={	// standard functions
	STD_VERSION,

	NULL,	// __ctype_ptr__
	__aeabi_idiv,
	__aeabi_idivmod,
	__aeabi_uidiv,
	__aeabi_ldivmod,

	iprintf_dbg,
	printf_dbg,	// don't use directly printf in order to debug in the main screen
	sprintf,
	fprintf,
	viprintf_dbg,
	vprintf_dbg,	// don't use directly vprintf in order to debug in the main screen
	vsprintf,
	vfprintf,
	sscanf,

	remove,
	mkdir,
	chdir,
	getcwd,
	rename,
	opendir,
	readdir,
	closedir,
	stat,

	strlen,
	strcpy,
	strncpy,
	strcmp,
	strcasecmp,
	strncmp,
	strcat,
	strchr,
	strrchr,
	strstr,
	endName,
	memcpy,
	memset,
	memchr,
	memcmp,
	alloca_no_macro,

	atoi,
	atoff	// float version of atof which is double
};

sNds _nds={	// libnds functions
	NDS_VERSION,

	swiWaitForVBlank,
	ki_scanKeys,
	ki_keysHeld,
	ki_keysDown,
	ki_keysDownRepeat,
	ki_keysSetRepeat,
	ki_keysUp,
	keysCurrent,
	touchRead,

	cosLerp,
	sinLerp,
	tanLerp
};

sX _x={		// xlibrary functions
	X_VERSION,

// xmalloc.h
	_xmalloc,
    xmalloc,
	_xcalloc,
    xcalloc,
	_xrealloc,
    xrealloc,
	_xfree,
    xfree,

// xstring.h
	endName,
	cmpext,
	xstrdup,
	xmemdup,

// xmem.h
	getMemFree
};

sF _f={		// file functions
	F_VERSION,

	fopen,
	fseek,
	ftell,
	rewind,
	fread,
	fgetc,
	fgets,
	fwrite,
	fputc,
	fputs,
	feof,
	ferror,
	fclose
};

sFL _fl={		// filelist functions
	FL_VERSION,

    fl_getcwd,
    fl_readcwd,
    fl_sort,
    fl_hash,
    fl_free
};

sLL _ll={   // linked lists functions (xlibrary/llist.h)
    LL_VERSION,

	ll_new_el,
	ll_append_el,
	ll_is_loop,
	ll_get_first_el,
	ll_get_nth_el,
	ll_get_last_el,
	ll_get_num_el,
	ll_for_each_data,
	ll_search_data,
	ll_sort,
	ll_free_el,
	ll_free_all,
	ll_free_all_handler
};

sLF _lf={   // lifo functions (xlibrary/lifo.h)
    LF_VERSION,

    lf_new,
    lf_is_valid,
    lf_push,
    lf_get_num_el,
    lf_pop,
    lf_free,
    lf_free_handler
};

sAPI _api={	// SunOS functions
	API_VERSION,

	getLibraryByFileExt,
    getLibraryByFileType,
    getLibraryByFileType_cfs,
	getLibraryById,
	newLibInstance,
	deleteLibInstance,

	getPluginByExt,
	runPlugin
};

sMM _mm={	// maxmod functions
	MM_VERSION,

	&isSStreaming,
	StreamOpen,
	mmStreamUpdate,
	StreamClose
};

sLibs _libs={
	LIBS_VERSION,

	.std=&_std,
	.nds=&_nds,
	.x=&_x,
	.f=&_f,
	.fl=&_fl,
	.ll=&_ll,
	.lf=&_lf,
	.api=&_api,
	.mm=&_mm
};

